package com.chat.handler;

import com.netty.imp.IMMessage;
import com.netty.imp.IMP;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import org.apache.commons.lang3.StringUtils;

import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 聊天客户端逻辑的实现
 * 主要的功能是完成客户端和服务端的会话，将控制台输入的文本信息转换为IMMessage对象发送到服务端，将服务端传过来的Java Object转换为文本输出到控制台。
 * 服务端包括从HTML页面发送过来的信息。也包括其他客户端从Java 控制台发送过来的信息
 *
 * @author kewei
 */
public class ChatClientHandler extends SimpleChannelInboundHandler<IMMessage> {

    private ChannelHandlerContext ctx;

    private String nickName;

    public ChatClientHandler(String nickName) {
        this.nickName = nickName;
    }

    /**
     * 启动客户端控制台
     */
    private void session() {
        new Thread(() -> {
            System.out.println(nickName + ",你好，请在控制台输入对话内容");
            IMMessage message = null;
            Scanner scanner = new Scanner(System.in);
            do {
                if (scanner.hasNext()) {
                    String input = scanner.nextLine();
                    if ("exit".equals(input)) {
                        message = new IMMessage(IMP.LOGOUT.name(), "Console", System.currentTimeMillis(), nickName);
                    } else {
                        message = new IMMessage(IMP.CHAT.name(), System.currentTimeMillis(), nickName, input);
                    }
                }
            } while (sendMsg(message));
            scanner.close();
        }).start();
    }

    /**
     * 发送消息
     *
     * @return
     */
    private boolean sendMsg(IMMessage msg) {
        ctx.channel().writeAndFlush(msg);
        return !msg.getCmd().equals(IMP.LOGOUT.name());
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        super.channelActive(ctx);
        this.ctx = ctx;
        IMMessage message = new IMMessage(IMP.LOGIN.name(), "Console", System.currentTimeMillis(), this.nickName);
        sendMsg(message);
        System.out.println("成功连接服务器，已执行登陆操作!");
        session();
    }

    /**
     * Is called for each message of type {@link I}.
     *
     * @param ctx the {@link ChannelHandlerContext} which this {@link SimpleChannelInboundHandler}
     *            belongs to
     * @param msg the message to handle
     * @throws Exception is thrown if an error occurred
     */
    @Override
    protected void messageReceived(ChannelHandlerContext ctx, IMMessage msg) throws Exception {
        System.out.println(" ====== > [client][ChatClientHandler] message received : " + msg.getContent());
        System.out.println(StringUtils.isBlank(msg.getSender()) ? "" : (msg.getSender() + ":") + removeHtmlTag(msg.getContent()));
    }


    /**
     * @param htmlStr
     * @return
     */
    private static String removeHtmlTag(String htmlStr) {
        //定义script的正则表达式
        String regEx_script = "<script[^>]*?>[\\s\\S]?<\\/script>";
        //定义style的正则表达式
        String regEx_style = "<style[^>]*?>[\\s\\S]?<\\/style>";
        //定义html的正则表达式
        String regEx_html = "<[^>]+>";
        Pattern p_script = Pattern.compile(regEx_script, Pattern.CASE_INSENSITIVE);
        Matcher m_script = p_script.matcher(htmlStr);
        htmlStr = m_script.replaceAll("");
        Pattern p_style = Pattern.compile(regEx_style, Pattern.CASE_INSENSITIVE);
        Matcher m_style = p_style.matcher(htmlStr);
        htmlStr = m_style.replaceAll("");
        Pattern p_html = Pattern.compile(regEx_html, Pattern.CASE_INSENSITIVE);
        Matcher m_html = p_html.matcher(htmlStr);
        htmlStr = m_html.replaceAll("");
        return htmlStr.trim();
    }

    /**
     * 异常处理
     *
     * @param ctx
     * @param cause
     * @throws Exception
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        super.exceptionCaught(ctx, cause);
        System.out.println("与服务器断开连接:" + cause.getMessage());
        ctx.close();
    }
}
